/**
 * @Author: colpu
 * @Date: 2025-03-29 19:38:16
 * @LastEditors: colpu ycg520520@qq.com
 * @LastEditTime: 2025-04-03 23:06:12
 * @
 * @Copyright (c) 2025 by colpu, All Rights Reserved.
 */
import path from "node:path";
import { readFileSync } from "node:fs";
import { fileURLToPath } from "node:url";
import BuiltinModule from "node:module";
import debugFactory from "debug";
const debug = debugFactory("@colpu/cli:utils");

// Guard against poorly mocked module constructors.
const Module =
  typeof module !== "undefined" && module.constructor.length > 1
    ? module.constructor
    : /* istanbul ignore next */
      BuiltinModule;

export const extensions = Module._extensions;
export const extensionNames = Object.keys(extensions).concat([
  ".cjs",
  ".mjs",
  ".ts",
]);
debug("Module extensions: %j", extensionNames);

export function fixFilepath(filepath) {
  if (filepath.startsWith("file://")) {
    filepath = fileURLToPath(filepath);
  }
  return filepath;
}
/**
 * @function loadFile
 * @description: 动态加载文件
 * @param {String} filepath 文件路径必须是绝对路径或者以file:///开头的文件
 * @param {Boolean} importDefaultOnly
 * @return {Promise}
 */
export async function loadFile(filepath, importDefaultOnly = true) {
  filepath = fixFilepath(filepath);
  try {
    // 如果不是js模块，只返回内容缓冲区
    const extname = path.extname(filepath);
    if (extname && !extensionNames.includes(extname)) {
      return readFileSync(filepath);
    }
    const promise = import(filepath).then((mod) => {
      if (importDefaultOnly) return mod.default;
      return mod;
    });
    return promise;
  } catch (e) {
    if (!(e instanceof Error)) {
      console.trace(e);
      throw e;
    }
    const err = new Error(
      `[@colpu/cli:utils] load file: ${filepath}, error: ${e.message}`
    );
    err.cause = e;
    debug("[loadFile] handle %s error: %s", filepath, e);
    throw err;
  }
}

export function readJSONSync(filepath) {
  return JSON.parse(readFileSync(fixFilepath(filepath), "utf8"));
}
